#include"tcpServer.h"
#include"ipAddressPort.h"
#include"logger.h"
#include"msg.h"

#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<string.h>

TcpServer::TcpServer(const IpAddressPort ipAddressPort)
{
   lfd_ = socket(AF_INET,SOCK_STREAM,0);
   if(-1 == lfd_)
   {
     LOG_FATAL << strerror(errno);
   }
   struct sockaddr_in ser;
   ser.sin_family = AF_INET;
   ser.sin_port = htons(ipAddressPort.GetPort());
   ser.sin_addr.s_addr = inet_addr(ipAddressPort.GetIpAddress().c_str());
   if(-1 == bind(lfd_,(struct sockaddr *)&ser,sizeof(ser)))
   {
     LOG_FATAL << strerror(errno);
   }
   if(-1 == listen(lfd_,5))
   {
    LOG_FATAL << strerror(errno);
   }
  
}
TcpServer::~TcpServer()
{
   if(-1 == close(lfd_))
   {
    LOG_FATAL << strerror(errno);
   }
   LOG_INFO<<"close lfd";
}
int TcpServer::Accept() const
{
  struct sockaddr_in cli;
   socklen_t len = sizeof(cli);
   int cfd = accept(lfd_,(struct sockaddr*)&cli,&len);
   if(-1 == cfd)
   {
    LOG_ERROR << strerror(errno);
    return -1;
   }else{
     char clientIpBuf[SMALL_BUF_LEN] ={0};
     if(!inet_ntop(AF_INET,&cli.sin_addr,clientIpBuf,SMALL_BUF_LEN))
     {
       LOG_ERROR << strerror(errno);
     }else{
       std::string clientIp(clientIpBuf);
       unsigned short clientPort = ntohs(cli.sin_port);
       IpAddressPort ipAddressPort(clientIp,clientPort);
       LOG_INFO<<cfd;
       LOG_INFO << ipAddressPort.ToString();
     }
   }
   return cfd;
}
int TcpServer::SendMsg(int cfd,const std::string msg)
{
   int numberOfSendByte = send(cfd,msg.c_str(),strlen(msg.c_str()),0);
   if(-1 == numberOfSendByte)
   {
     LOG_ERROR <<strerror(errno);
   }
   return numberOfSendByte;
}
Msg TcpServer::RecvMsg(int cfd)
{
   char buff[LAGE_BUF_LEN] ={0};
   int numberOfRecvBytes = recv(cfd,buff,LAGE_BUF_LEN ,0);
   if(-1 == numberOfRecvBytes)
   {
    LOG_ERROR << strerror(errno);
   }
   return Msg(buff,numberOfRecvBytes);
}
int TcpServer::GetLfd()const
{
   return lfd_;
}
